package chair.core;

import java.util.ArrayList;

public interface CoreModel {

	/**
	 * Attention, il est nécessaire d'ajouter chaque modèle à la liste des
	 * modèles disponibles. Pour cela le nom de la classe du nouveau modèle doit
	 * être ajouté à la liste présente dans le fichier models.Model dans le
	 * dossier META-INF/services. Cela permet de charger au lancement du
	 * programme la liste des modèles disponible.
	 * 
	 * Si un modèle n'est pas ajouté à cette liste, il ne sera pas possible de
	 * l'utiliser lors du lancement d'une nouvelle simulation.
	 */

	/**
	 * Méthode d'initialisation du model. Elle est appellé au début de la
	 * première simulation du modèle.
	 * 
	 * @param stimuli
	 *            Vecteur contenant l'ensemble des stimuli utilisé durant
	 *            l'expérience.
	 */
	public void initializeModel(ArrayList<Stimulus> stimuli);

	/**
	 * Si on ne peut pas forcément donner au model tous les stilumi qu'il va
	 * rencontrer a priori avec initializeModel() on pourra avec cette foncion
	 * les ajouter un à un au fur et à mesure des besoins
	 * 
	 * Lève IllegalArgumentException si on tente d'ajouter un stimulus déjà
	 * présent
	 * 
	 * @param stim
	 *            Le stimulus qui va être ajouté au modèle
	 */
	public void plugStimulus(Stimulus stim);

	/**
	 * Fonction de traitement d'un évènement. Elle est appelée au début et à la
	 * fin d'un stimulus et correspond au front montant et descendant du
	 * stimulus.
	 * 
	 * @param stimulus
	 *            L'évènement concerné par le front montant ou descendant
	 * @param risingEdge
	 *            Vrai si c'est un front montant, faux sinon.
	 */
	public void handleEvent(Stimulus stimulus, boolean risingEdge);

	/**
	 * Fonction de test du modèle. Le modèle doit dire si il "pense" que le
	 * stimulus fournit en argument va bientôt survenir. Aucune modification du
	 * modèle ne doit être effectuée durant ce test.
	 * 
	 * @param checkedStimulus
	 *            Le stimulus vérifié
	 * @return Vrai si le modèle prévoit que le checkedStimulus surviennent sous
	 *         peu, Faux sinon.
	 */
	public boolean checkForecast(Stimulus checkedStimulus);

	/**
	 * Afin de savoir ce que prédit un stimulus particulier. Une version de
	 * computeForecastProbability() non pas appliquée aux stimuli actuellement
	 * en mémoire mais à celui de la requête. Tout comme checkForecast seuls les
	 * fronts montants sont prédits
	 * 
	 * @param stim
	 *            le stimulus à tester
	 * @param risingEdge
	 *            on donne la possibilité de tester front montant ou descendant
	 *            individuellement
	 * @return liste des stimuli qu'il prévoit (objets non liés aux Stimulus du
	 *         modèle)
	 */
	public ArrayList<Stimulus> checkForecastProbability(Stimulus stim,
			boolean risingEdge);

	/**
	 * Fonction appellé à chaque tick de l'expérience afin que le modèle puisse
	 * enregistrer ses résultats correctement et mesurer l'écoulement du temps.
	 * Un tick correspond a stepTime milliseconde.
	 */
	public void tick(long t);

	@Override
	public String toString();

	public void setName(String newName);

	public String getName();
	
	/** À des fins de contrôle, renvoie des infos sur le modèle */
	public String debug();

}
